﻿using System;
using System.Collections.Generic;
using HK.Core.Common.Protocol.Data;
using UnityEngine;
using HCompareOptions = HK.Core.Common.Protocol.Data.CompareOptions;

namespace HK.Core.Common.Data
{
    /// <summary>
    /// 白名单
    /// </summary>
    [Serializable]
    public class WhiteList : FilterData<WhiteList>, IWhiteList
    {

#region Create

        /// <summary>
        /// 创建白名单
        /// </summary>
        /// <returns>白名单</returns>
        public static WhiteList Create()
        {
            return new WhiteList();
        }

#endregion

        /// <summary>
        /// 保护构造函数
        /// </summary>
        /// <param name="iCompareOptions">比较选项</param>
        /// <param name="iExtensions">扩展列表</param>
        protected WhiteList(int iCompareOptions =(int)HCompareOptions.None, IFileExtensions iExtensions = null) : 
            base(iCompareOptions, iExtensions) { }

#region Targets

        [SerializeField]
        private List<string> list = new List<string>();
        /// <summary>
        /// 列表
        /// </summary>
        public List<string> List => list;
        
        /// <summary>
        /// 是否包含在白名单中
        /// </summary>
        /// <param name="iTarget">目标</param>
        /// <returns>true:包含; false:不包含;</returns>
        public virtual bool Contains(string iTarget)
        {
            if (string.IsNullOrEmpty(iTarget) || 0 >= Count) return false;
            return list.Exists(iO => iO.ToLower().Equals(iTarget.ToLower()));
        }

        /// <summary>
        /// 存在校验
        /// </summary>
        /// <param name="iTarget">目标对象</param>
        /// <returns>true:存在; false:不存在;</returns>
        protected virtual bool Exist(string iTarget) => list.Exists(iO => iO.Equals(iTarget));

        /// <summary>
        /// 追加目标对象
        /// <para>* 无效的目标对象，或者未通过过滤验证的，都将视为失败</para>
        /// </summary>
        /// <param name="iTarget">目标对象</param>
        /// <returns>true:追加成功; false:追加失败;</returns>
        public bool AddTarget(string iTarget)
        {
            if (string.IsNullOrEmpty(iTarget) || !Filter(iTarget)) return false;

            // 已存在
            if (Exist(iTarget)) return true;
            
            list.Add(iTarget);
            return true;
        }

        /// <summary>
        /// 追加目标对象
        /// <para>* 无效的目标对象，或者未通过过滤验证的，都将视为失败</para>
        /// </summary>
        /// <param name="iTargets">目标对象</param>
        /// <returns>成功追加数量</returns>
        public virtual int AddTargets(IReadOnlyList<string> iTargets)
        {
            if (null == iTargets || 0 >= iTargets.Count) return 0;

            var addedCount = 0;
            var count = iTargets.Count;
            for (var idx = 0; idx < count; ++idx)
            {
                var target = iTargets[idx];
                if (AddTarget(target))
                {
                    ++addedCount;
                }
            }
            
            return addedCount;
        }

#endregion

#region Filter

        [SerializeField]
        private List<string> extension = new List<string>();
        /// <summary>
        /// 过滤扩展选项
        /// <para>* 可以追加列入后缀名等信息</para>
        /// </summary>
        public List<string> Extension => extension;

        /// <summary>
        /// 过滤
        /// </summary>
        /// <param name="iTarget">目标对象</param>
        /// <returns>true:通过过滤; false:未通过过滤;</returns>
        public override bool Filter(string iTarget) => true;

#endregion

        /// <summary>
        /// 数量
        /// </summary>
        public int Count => list.Count;

        /// <summary>
        /// 应用数据
        /// </summary>
        /// <param name="iData">数据</param>
        /// <param name="iImport">导入标志位(true:从相应的*.json文件导入; false:反之;)</param>
        /// <returns>true:有变更; false:无变更;</returns>
        public override bool ApplyData(IJsonData iData, bool iImport = false)
        {
            if (null == iData || !iData.Valid) return false;

            var dirty = base.ApplyData(iData, iImport);
            if (dirty && !iImport)
            {
                Dirty = true;
            }

            if (iData is IWhiteList whiteList)
            {
                list = UpdateValue(list, whiteList.List, iImport);
            }

            return Dirty;
        }

        /// <summary>
        /// 清空
        /// </summary>
        public override void Clear()
        {
            base.Clear();
            
            list.Clear();
        }
    }
}
